home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d12
/
v10n22.arc
/
RECORD1.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-12-08
|
17KB
|
427 lines
/*---------------------------------------------------------
RECORD1.C -- Multimedia Windows Waveform Audio Recorder
(c) Charles Petzold, 1991
---------------------------------------------------------*/
#include <windows.h>
#include <mmsystem.h>
#include <string.h>
#include "record1.h"
#define BUFFER_SIZE 16384 // Must be multiple of 2 for memory copies
BOOL FAR PASCAL DlgProc (HWND, WORD, WORD, LONG) ;
static char szAppName [] = "Record1" ;
int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow)
{
FARPROC lpDlgProc ;
lpDlgProc = MakeProcInstance (DlgProc, hInstance) ;
DialogBox (hInstance, szAppName, NULL, lpDlgProc) ;
FreeProcInstance (lpDlgProc) ;
return 0 ;
}
void HugeMemRev (unsigned char huge *pBuffer, unsigned long lLength)
{
unsigned char c ;
unsigned long l ;
for (l = 0 ; l < lLength / 2 ; l++)
{
c = pBuffer [l] ;
pBuffer [l] = pBuffer [lLength - l - 1] ;
pBuffer [lLength - l - 1] = c ;
}
}
BOOL FAR PASCAL DlgProc (HWND hwnd, WORD message, WORD wParam, LONG lParam)
{
static BOOL bRecording, bPlaying, bReverse, bPaused,
bEnding, bTerminating ;
static BYTE FAR * pBuffer ;
static BYTE huge * pSaveBuffer ;
static char szOpenError[] = { "Error opening waveform audio!" } ;
static char szMemError[] = { "Error allocating memory!" } ;
static DWORD dwDataLength, dwRepetitions = 1 ;
static GLOBALHANDLE hSaveBuffer, hNewBuffer, hBuffer, hWaveHdr ;
static HWAVEIN hWaveIn ;
static HWAVEOUT hWaveOut ;
static LPWAVEHDR pWaveHdr ;
static PCMWAVEFORMAT pcm ;
switch (message)
{
case WM_INITDIALOG:
// Allocate Memory for Wave Header
hWaveHdr = GlobalAlloc (GHND | GMEM_SHARE, sizeof (WAVEHDR)) ;
pWaveHdr = (LPWAVEHDR) GlobalLock (hWaveHdr) ;
// Allocate Memory for Save Buffer
hSaveBuffer = GlobalAlloc (GHND | GMEM_SHARE, 1) ;
pSaveBuffer = GlobalLock (hSaveBuffer) ;
return TRUE ;
case WM_COMMAND:
switch (wParam)
{
case ID_RECORD_BEG:
// Allocate Buffer Memory
hBuffer = GlobalAlloc (GHND | GMEM_SHARE,
BUFFER_SIZE) ;
if (hBuffer == NULL)
{
MessageBeep (MB_ICONEXCLAMATION) ;
MessageBox (hwnd, szMemError, szAppName,
MB_ICONEXCLAMATION | MB_OK) ;
return TRUE ;
}
pBuffer = GlobalLock (hBuffer) ;
// Open Waveform Audio for Input
pcm.wf.wFormatTag = WAVE_FORMAT_PCM ;
pcm.wf.nChannels = 1 ;
pcm.wf.nSamplesPerSec = 11025 ;
pcm.wf.nAvgBytesPerSec = 11025 ;
pcm.wf.nBlockAlign = 1 ;
pcm.wBitsPerSample = 8 ;
if (waveInOpen (&hWaveIn, 0, &pcm.wf, hwnd, 0L,
CALLBACK_WINDOW))
{
GlobalUnlock (hBuffer) ;
GlobalFree (hBuffer) ;
MessageBeep (MB_ICONEXCLAMATION) ;
MessageBox (hwnd, szOpenError, szAppName,
MB_ICONEXCLAMATION | MB_OK) ;
}
return TRUE ;
case ID_RECORD_END:
// Reset Input to Return Last Buffer
bEnding = TRUE ;
waveInReset (hWaveIn) ;
return TRUE ;
case ID_PLAY_BEG:
// Open Waveform Audio for Output
pcm.wf.wFormatTag = WAVE_FORMAT_PCM ;
pcm.wf.nChannels = 1 ;
pcm.wf.nSamplesPerSec = 11025 ;
pcm.wf.nAvgBytesPerSec = 11025 ;
pcm.wf.nBlockAlign = 1 ;
pcm.wBitsPerSample = 8 ;
if (waveOutOpen (&hWaveOut, 0, &pcm.wf, hwnd, 0L,
CALLBACK_WINDOW))
{
MessageBeep (MB_ICONEXCLAMATION) ;
MessageBox (hwnd, szOpenError, szAppName,
MB_ICONEXCLAMATION | MB_OK) ;
}
return TRUE ;
case ID_PLAY_PAUSE:
// Pause or Restart Output
if (!bPaused)
{
waveOutPause (hWaveOut) ;
SetDlgItemText (hwnd, ID_PLAY_PAUSE, "Resume") ;
bPaused = TRUE ;
}
else
{
waveOutRestart (hWaveOut) ;
SetDlgItemText (hwnd, ID_PLAY_PAUSE, "Pause") ;
bPaused = FALSE ;
}
return TRUE ;
case ID_PLAY_END:
// Reset Output for Close Preparation
bEnding = TRUE ;
waveOutReset (hWaveOut) ;
return TRUE ;
case ID_PLAY_REV:
// Reverse Save Buffer and Play
bReverse = TRUE ;
HugeMemRev (pSaveBuffer, dwDataLength) ;
SendMessage (hwnd, WM_COMMAND, ID_PLAY_BEG, 0L) ;
return TRUE ;
case ID_PLAY_REP:
// Set Infinite Repetitions and Play
dwRepetitions = -1 ;
SendMessage (hwnd, WM_COMMAND, ID_PLAY_BEG, 0L) ;
return TRUE ;
case ID_PLAY_SPEED:
// Open Waveform Audio for Fast Output
pcm.wf.wFormatTag = WAVE_FORMAT_PCM ;
pcm.wf.nChannels = 1 ;
pcm.wf.nSamplesPerSec = 22050 ;
pcm.wf.nAvgBytesPerSec = 22050 ;
pcm.wf.nBlockAlign = 1 ;
pcm.wBitsPerSample = 8 ;
if (waveOutOpen (&hWaveOut, 0, &pcm.wf, hwnd, 0L,
CALLBACK_WINDOW))
{
MessageBeep (MB_ICONEXCLAMATION) ;
MessageBox (hwnd, szOpenError, szAppName,
MB_ICONEXCLAMATION | MB_OK) ;
}
return TRUE ;
}
break ;
case MM_WIM_OPEN:
// Shrink Down the Save Buffer
GlobalUnlock (hSaveBuffer) ;
hSaveBuffer = GlobalReAlloc (hSaveBuffer, 1, GHND) ;
pSaveBuffer = GlobalLock (hSaveBuffer) ;
// Enable and Disable Buttons
EnableWindow (GetDlgItem (hwnd, ID_RECORD_BEG), FALSE) ;
EnableWindow (GetDlgItem (hwnd, ID_RECORD_END), TRUE) ;
EnableWindow (GetDlgItem (hwnd, ID_PLAY_BEG), FALSE) ;
EnableWindow (GetDlgItem (hwnd, ID_PLAY_PAUSE), FALSE) ;
EnableWindow (GetDlgItem (hwnd, ID_PLAY_END), FALSE) ;
EnableWindow (GetDlgItem (hwnd, ID_PLAY_REV), FALSE) ;
EnableWindow (GetDlgItem (hwnd, ID_PLAY_REP), FALSE) ;
EnableWindow (GetDlgItem (hwnd, ID_PLAY_SPEED), FALSE) ;
SetFocus (GetDlgItem (hwnd, ID_RECORD_END)) ;
// Set Up Header
pWaveHdr->lpData = pBuffer ;
pWaveHdr->dwBufferLength = BUFFER_SIZE ;
pWaveHdr->dwBytesRecorded = 0L ;
pWaveHdr->dwUser = 0L ;
pWaveHdr->dwFlags = 0L ;
pWaveHdr->dwLoops = 1L ;
pWaveHdr->lpNext = NULL ;
pWaveHdr->reserved = 0L ;
// Prepare and Add
waveInPrepareHeader (hWaveIn, pWaveHdr, sizeof (WAVEHDR)) ;
waveInAddBuffer (hWaveIn, pWaveHdr, sizeof (WAVEHDR)) ;
// Begin Sampling
bRecording = TRUE ;
bEnding = FALSE ;
dwDataLength = 0L ;
waveInStart (hWaveIn) ;
return TRUE ;
case MM_WIM_DATA:
// Unprepare Header
waveInUnprepareHeader (hWaveIn, pWaveHdr, sizeof (WAVEHDR)) ;
// Reallocate Save Buffer Memory
GlobalUnlock (hSaveBuffer) ;
hNewBuffer = GlobalReAlloc (hSaveBuffer, dwDataLength +
pWaveHdr->dwBytesRecorded, 0) ;
if (hNewBuffer == NULL)
{
pSaveBuffer = GlobalLock (hSaveBuffer) ;
waveInClose (hWaveIn) ;
MessageBeep (MB_ICONEXCLAMATION) ;
MessageBox (hwnd, szMemError, szAppName,
MB_ICONEXCLAMATION | MB_OK) ;
return TRUE ;
}
hSaveBuffer = hNewBuffer ;
pSaveBuffer = GlobalLock (hSaveBuffer) ;
_fmemcpy ((char far *) (pSaveBuffer + dwDataLength), pBuffer,
(int) pWaveHdr->dwBytesRecorded) ;
dwDataLength += pWaveHdr->dwBytesRecorded ;
if (bEnding)
{
waveInClose (hWaveIn) ;
return TRUE ;
}
// Set the Header, Prepare and Add
pWaveHdr->lpData = pBuffer ;
pWaveHdr->dwBufferLength = BUFFER_SIZE ;
pWaveHdr->dwBytesRecorded = 0L ;
pWaveHdr->dwUser = 0L ;
pWaveHdr->dwFlags = 0L ;
pWaveHdr->dwLoops = 1L ;
pWaveHdr->lpNext = NULL ;
pWaveHdr->reserved = 0L ;
waveInPrepareHeader (hWaveIn, pWaveHdr, sizeof (WAVEHDR)) ;
waveInAddBuffer (hWaveIn, pWaveHdr, sizeof (WAVEHDR)) ;
return TRUE ;
case MM_WIM_CLOSE:
// Free the Buffer Memory
GlobalUnlock (hBuffer) ;
GlobalFree (hBuffer) ;
// Enable and Disable Buttons
EnableWindow (GetDlgItem (hwnd, ID_RECORD_BEG), TRUE) ;
EnableWindow (GetDlgItem (hwnd, ID_RECORD_END), FALSE) ;
SetFocus (GetDlgItem (hwnd, ID_RECORD_BEG)) ;
if (dwDataLength > 0)
{
EnableWindow (GetDlgItem (hwnd, ID_PLAY_BEG), TRUE) ;
EnableWindow (GetDlgItem (hwnd, ID_PLAY_PAUSE), FALSE) ;
EnableWindow (GetDlgItem (hwnd, ID_PLAY_END), FALSE) ;
EnableWindow (GetDlgItem (hwnd, ID_PLAY_REP), TRUE) ;
EnableWindow (GetDlgItem (hwnd, ID_PLAY_REV), TRUE) ;
EnableWindow (GetDlgItem (hwnd, ID_PLAY_SPEED), TRUE) ;
SetFocus (GetDlgItem (hwnd, ID_PLAY_BEG)) ;
}
bRecording = FALSE ;
if (bTerminating)
SendMessage (hwnd, WM_SYSCOMMAND, SC_CLOSE, 0L) ;
return TRUE ;
case MM_WOM_OPEN:
// Enable and Disable Buttons
EnableWindow (GetDlgItem (hwnd, ID_RECORD_BEG), FALSE) ;
EnableWindow (GetDlgItem (hwnd, ID_RECORD_END), FALSE) ;
EnableWindow (GetDlgItem (hwnd, ID_PLAY_BEG), FALSE) ;
EnableWindow (GetDlgItem (hwnd, ID_PLAY_PAUSE), TRUE) ;
EnableWindow (GetDlgItem (hwnd, ID_PLAY_END), TRUE) ;
EnableWindow (GetDlgItem (hwnd, ID_PLAY_REP), FALSE) ;
EnableWindow (GetDlgItem (hwnd, ID_PLAY_REV), FALSE) ;
EnableWindow (GetDlgItem (hwnd, ID_PLAY_SPEED), FALSE) ;
SetFocus (GetDlgItem (hwnd, ID_PLAY_END)) ;
// Set Up Header
pWaveHdr->lpData = (char far *) pSaveBuffer ;
pWaveHdr->dwBufferLength = dwDataLength ;
pWaveHdr->dwBytesRecorded = 0L ;
pWaveHdr->dwUser = 0L ;
pWaveHdr->dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP ;
pWaveHdr->dwLoops = dwRepetitions ;
pWaveHdr->lpNext = NULL ;
pWaveHdr->reserved = 0L ;
// Prepare and Write
waveOutPrepareHeader (hWaveOut, pWaveHdr, sizeof (WAVEHDR)) ;
waveOutWrite (hWaveOut, pWaveHdr, sizeof (WAVEHDR)) ;
bEnding = FALSE ;
bPlaying = TRUE ;
return TRUE ;
case MM_WOM_DONE:
waveOutUnprepareHeader (hWaveOut, pWaveHdr, sizeof (WAVEHDR)) ;
waveOutClose (hWaveOut) ;
return TRUE ;
case MM_WOM_CLOSE:
// Enable and Disable Buttons
EnableWindow (GetDlgItem (hwnd, ID_RECORD_BEG), TRUE) ;
EnableWindow (GetDlgItem (hwnd, ID_RECORD_END), TRUE) ;
EnableWindow (GetDlgItem (hwnd, ID_PLAY_BEG), TRUE) ;
EnableWindow (GetDlgItem (hwnd, ID_PLAY_PAUSE), FALSE) ;
EnableWindow (GetDlgItem (hwnd, ID_PLAY_END), FALSE) ;
EnableWindow (GetDlgItem (hwnd, ID_PLAY_REV), TRUE) ;
EnableWindow (GetDlgItem (hwnd, ID_PLAY_REP), TRUE) ;
EnableWindow (GetDlgItem (hwnd, ID_PLAY_SPEED), TRUE) ;
SetFocus (GetDlgItem (hwnd, ID_PLAY_BEG)) ;
SetDlgItemText (hwnd, ID_PLAY_PAUSE, "Pause") ;
bPaused = FALSE ;
dwRepetitions = 1 ;
bPlaying = FALSE ;
if (bReverse)
{
HugeMemRev (pSaveBuffer, dwDataLength) ;
bReverse = FALSE ;
}
if (bTerminating)
SendMessage (hwnd, WM_SYSCOMMAND, SC_CLOSE, 0L) ;
return TRUE ;
case WM_SYSCOMMAND:
switch (wParam)
{
case SC_CLOSE:
if (bRecording)
{
bTerminating = TRUE ;
bEnding = TRUE ;
waveInReset (hWaveIn) ;
return TRUE ;
}
if (bPlaying)
{
bTerminating = TRUE ;
bEnding = TRUE ;
waveOutReset (hWaveOut) ;
return TRUE ;
}
GlobalUnlock (hWaveHdr) ;
GlobalFree (hWaveHdr) ;
GlobalUnlock (hSaveBuffer) ;
GlobalFree (hSaveBuffer) ;
EndDialog (hwnd, 0) ;
return TRUE ;
}
break ;
}
return FALSE ;
}